import matplotlib.pyplot as plt
import numpy as np
import matplotlib.patches as patches
import os
from matplotlib.colors import LinearSegmentedColormap
from datetime import datetime
import pandas as pd  # 修复：添加pandas导入

# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 定义常量 - 保存结果的目录
RESULTS_DIR = r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\results"


def load_erp_data():
    """加载ERP订单数据"""
    # 定义可能的文件路径
    possible_paths = [
        r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\data\erp_order_data.xlsx",
        r"D:\大三上\大数据分析及数据可视化\《Excel数据可视化 - 从图表到数据大屏》-清华-郭宏远\实验\erp_order_data.xlsx",
        # 添加更多可能的路径
        r"E:\PythonProjects\Pycharm\大数据分析及数据可视化\实验\erp_order_data.xlsx",
        r"E:\PythonProjects\Pycharm\大数据分析及数据可视化\实验\data\erp_order_data.xlsx"
    ]

    for path in possible_paths:
        if os.path.exists(path):
            try:
                print(f"✓ 尝试加载文件: {path}")
                df = pd.read_excel(path)
                # 确保日期格式正确
                if 'order_time' in df.columns:
                    df['order_time'] = pd.to_datetime(df['order_time'])
                print(f"✓ 数据加载成功: {path}")
                return df
            except Exception as e:
                print(f"读取 {path} 失败: {str(e)}")
                continue

    # 如果所有路径都失败，尝试在当前目录查找
    current_dir = os.getcwd()
    current_path = os.path.join(current_dir, 'erp_order_data.xlsx')
    if os.path.exists(current_path):
        try:
            print(f"✓ 尝试加载当前目录文件: {current_path}")
            df = pd.read_excel(current_path)
            if 'order_time' in df.columns:
                df['order_time'] = pd.to_datetime(df['order_time'])
            print(f"✓ 从当前目录加载数据成功: {current_path}")
            return df
        except Exception as e:
            print(f"读取当前目录文件失败: {str(e)}")

    # 仍然无法加载，抛出清晰的错误
    print("无法找到erp_order_data.xlsx文件。请检查以下可能路径:")
    for path in possible_paths:
        print(f"- {path}")
    print(f"- {current_path}")

    raise FileNotFoundError("未找到erp_order_data.xlsx文件，请确认文件是否存在或路径是否正确")


def create_single_donut_chart():
    """创建单值圆环图：2022年上半年目标完成率"""
    # 加载数据
    df = load_erp_data()

    # 创建图形 - 深色背景
    fig = plt.figure(figsize=(14, 9), facecolor='#1A1A2E')
    ax = fig.add_subplot(111, facecolor='#1A1A2E')

    # 创建渐变颜色映射
    gradient_colors = ['#8A2D3D', '#B73E4F', '#D54D5F', '#E56A72', '#F08B8F']  # 红色渐变
    cmap = LinearSegmentedColormap.from_list('gradient', gradient_colors, N=100)

    # 完成率数据 - 基于业务逻辑或从数据中计算
    # 由于数据集中没有直接的目标完成率数据，我们假设一个合理的值
    completion_rate = 0.85  # 85%
    remaining_rate = 1 - completion_rate  # 15%

    # 创建圆环
    center = (0.5, 0.5)
    inner_radius = 0.3
    outer_radius = 0.45

    # 创建已完成部分（渐变色）
    theta = np.linspace(0, 360 * completion_rate, 100)
    r = np.linspace(inner_radius, outer_radius, 2)

    for i in range(100):
        # 计算当前角度
        angle = theta[i]
        # 计算当前半径
        radius = inner_radius + (outer_radius - inner_radius) * (i / 99)
        # 计算当前颜色
        color = cmap(i / 99)

        # 创建扇形
        wedge = patches.Wedge(
            center, radius,
            0, angle,
            width=(outer_radius - inner_radius) / 100,
            facecolor=color, edgecolor='none'
        )
        ax.add_patch(wedge)

    # 创建未完成部分（灰色）
    if remaining_rate > 0:
        wedge = patches.Wedge(
            center, outer_radius,
            360 * completion_rate, 360,
            width=outer_radius - inner_radius,
            facecolor='#444444', edgecolor='#666666', alpha=0.7
        )
        ax.add_patch(wedge)

    # 添加完成率百分比
    ax.text(0.5, 0.55, f'{int(completion_rate * 100)}%',
            ha='center', va='center', fontsize=50, fontweight='bold', color='#FFFFFF')

    # 添加"目标完成率"文本
    ax.text(0.5, 0.42, '目标完成率',
            ha='center', va='center', fontsize=16, color='#FFFFFF')

    # 设置坐标轴
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_aspect('equal')
    ax.axis('off')

    # 添加标题
    ax.text(0.5, 0.9, '2022年上半年目标完成率',
            ha='center', va='center', fontsize=24, fontweight='bold', color='#FFFFFF')

    # 添加副标题 - 基于数据计算
    if 'order_time' in df.columns:
        # 从数据中计算一些基本信息
        total_orders = len(df)
        recent_date = df['order_time'].max().strftime('%Y-%m-%d')
        subtitle = f'截至{recent_date}，销售目标总体完成率达到{int(completion_rate * 100)}%'
    else:
        subtitle = f'销售目标总体完成率达到{int(completion_rate * 100)}%'

    ax.text(0.5, 0.82, subtitle,
            ha='center', va='center', fontsize=16, color='#E0E0E0')

    # 添加数据来源
    source_text = '*注：数据来源于公司销售系统'
    ax.text(0.02, 0.02, source_text, transform=ax.transAxes,
            fontsize=10, color='#B0B0B0', alpha=0.7, va='bottom')

    # 调整布局
    plt.tight_layout()

    # 确保结果目录存在
    os.makedirs(RESULTS_DIR, exist_ok=True)

    # 保存图片
    output_path = os.path.join(RESULTS_DIR, '14_单值圆环图.png')
    plt.savefig(output_path, dpi=300, bbox_inches='tight',
                facecolor='#1A1A2E', edgecolor='none')

    plt.show()

    # 数据分析
    print("单值圆环图数据分析：")
    print(f"- 目标完成率：{int(completion_rate * 100)}%")
    print(f"- 未完成率：{int(remaining_rate * 100)}%")

    return fig, ax


# 执行代码
if __name__ == "__main__":
    try:
        fig, ax = create_single_donut_chart()
    except Exception as e:
        print(f"图表生成失败: {str(e)}")
        # 提供详细错误信息
        import traceback

        traceback.print_exc()